package com.brillilab.common.utils;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 流加解密工具
 *
 * @author wmh
 */
public class FileSecurityUtil {

    /**
     * 加密输入流
     *
     * @param in
     * @param secretKey
     * @return
     */
    public static InputStream encryptInputStream(InputStream in,String secretKey) {

        String tempKey=genTempKeyString(secretKey);

        Cipher cipher=initCipher(Cipher.ENCRYPT_MODE,tempKey);

        return new CipherInputStream(in,cipher);

    }

    /**
     * 解密输入流
     *
     * @param out
     * @param secretKey
     * @return
     */
    public static InputStream decryptInputStream(InputStream input,String secretKey){

        String tempKey=genTempKeyString(secretKey);

        Cipher cipher=initCipher(Cipher.DECRYPT_MODE,tempKey);

        return new CipherInputStream(input,cipher);
    }

    /**
     * 解密输出流
     *
     * @param out
     * @param secretKey
     * @return
     */
    public static OutputStream decryptOutputStream(OutputStream out,String secretKey) {

        String tempKey=genTempKeyString(secretKey);

        Cipher cipher=initCipher(Cipher.DECRYPT_MODE,tempKey);

        return new CipherOutputStream(out,cipher);
    }

    /**
     * 加密器
     *
     * @param cipherModel
     * @param keyRule
     * @return
     */
    private static Cipher initCipher(int cipherModel,String keyRule) {


        try {
            byte[] keyBytes=keyRule.substring(0,8).getBytes("ASCII");
            byte[] IVBytes=keyRule.substring(8,16).getBytes("ASCII");

            SecretKeySpec key=new SecretKeySpec(keyBytes,"DES");
            IvParameterSpec IV=new IvParameterSpec(IVBytes);

            Cipher cipher=Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(cipherModel,key,IV);
            return cipher;
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException |
                InvalidAlgorithmParameterException | NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取临时key
     * @param keyStr
     * @return
     */
    private static String genTempKeyString(String keyStr) {
        Assert.isTrue(!StringUtils.isEmpty(keyStr) && keyStr.length() == 16,"keyStr must be formed with 16 characters");
        String tempKey=null;
        tempKey=keyStr.substring(14,16) + keyStr.substring(0,2) + keyStr.substring(10,12) + keyStr.substring(8,10);
        tempKey+=keyStr.substring(12,14) + keyStr.substring(6,8) + keyStr.substring(2,4) + keyStr.substring(4,6);
        return tempKey;
    }
}
